#ifndef PERSO_INCLUDED
#define PERSO_INCLUDED

#include <stdio.h>
#include <stdlib.h>
#include "objet.h"

/**
 * \file perso.h
 * \brief Module personnage
 * \author Thomas Gauvain / Nathanaël Desjobert
 * \date 04 Juin 2013
 *
 * Module gérant les personnages (joueurs et monstres).
 *
 */


/**
 * Module personnage : Structure commune au(x) joueur(s) et aux monstres.
 * Ce module permet de manipuler les points de vie, la position, la vitesse,
 * l'état (vivant, endormi, mort, ...) ainsi que l'objet tenu par un personnage.
 * **/

/**
    \enum typepers
    \brief type pour différencier les différents personnages
    **/


typedef enum{
    JOUEUR=0,
    POULE=1,
    CREEPER=2,
    BOO=3,
    TETEMORT=4,
    MOUCHE=5,
    CHAUVSOURIS=6,
    LIMACE=7,
    ZOMBIE=8,
    OEIL=9,
    CHOMP=10,
    SPACEIN=11,
    MEATBOYS=12,
    ISAAC=13,
    BEBEFAUCHEUR=14,
    FAUCHBEBE=15,
    SQUELETTE1=16,
    SQUELETTE2=17,
    ENDER=18,
    LARVEBOSS=19,
    SPACEINBOSS=20
       } typepers;

/**
    \struct Perso
    \brief Structure des personnages

    Contient toutes les caractéristiques des personnages (pv, états, positions, vecteurs vitesses, ...)
**/
struct sPerso {
    /* Pour le Déplacement */
    char allervert;
    char allerhor;
    float temps;
	double VectVitesse[2];/** Permet de décrire la vitesse ainsi que la direction de notre personnage **/
	int VitesseMax;
	int Posintx;
	int Posinty;
	double Posdoubx;
	double Posdouby;

	/* Pour le gameplay */
	int hitboxx;
    int hitboxy;
	int VieMax;
	char Etat; /** Vivant : V; Mort : M; Invincible : I**/
	int PointDeVie;
	Objet *  Objet[2];
	typepers TypePerso; /** Permet de différencier le type de monstre ainsi que le joueur **/
	float timer;

	};
typedef struct sPerso Perso;

/** Fonction get et set **/
char GetallervertPerso(Perso * P);
char GetallerhorPerso(Perso * P);
int GetPointDeViePerso(Perso * P);
int getViemaxPerso(Perso * P);
int GetPosintxPerso(Perso * P);
int GetPosintyPerso(Perso * P);
double GetPosdoubxPerso(Perso * P);
double GetPosdoubyPerso(Perso * P);
char GetEtatPerso(Perso * P);
int GetVitmaxPerso(Perso* P);
float GetTimerPerso(Perso * P);
float GetTimer2Perso(Perso *P);

double GetVectVitessexPerso(Perso * P);
double GetVectVitesseyPerso(Perso * P);
Objet* GetObjetprincipPerso(Perso * P);
Objet* GetObjetsecondPerso(Perso * P);
typepers GetTypePerso(Perso * P);
int GethitboxxPerso(Perso * P);
int GethitboxyPerso(Perso * P);

void SetallerPerso (Perso * P, char vert, char hor);
void SethitboxPerso(Perso * P, int x, int y);
void SetVieMaxPerso(Perso * P, int pvmax);
void SetPointDeViePerso(Perso * P, int pv);
void SetPosintxPerso(Perso * P, int x);
void SetPosintyPerso(Perso * P, int y);
void SetPosdoubxPerso(Perso * P, double x);
void SetVectVitessePerso(Perso * P,double x, double y);
void SetPosdoubyPerso(Perso * P, double y);
void SetEtatPerso(Perso * P, char Etat);
void SetTypePerso(Perso * P, typepers T);
void SetVitesseMax(Perso * P, int VitMax);
void SetTimerPerso(Perso * P);
void SetTimer2Perso(Perso *P);

/** Initialisation de personnage **/

/**
    \brief Fait l'initialisation d'un personnage joueur
    \return Perso* initialisé
    \param [in] typepers T

    Si typepers != JOUEUR, renvoit NULL
    */
Perso * InitJoueurPerso(typepers T);

/**
    \brief fait un printf des attributs du perso
    \param [in] Perso * P
    */

void afficherattributpersonnage(Perso* P);


/**
    \brief Fait l'initialisation d'un personnage monstre à partir d'un fichier conf
    \param [in] Perso * P
    \param [in] typepers T
    \param [in] char * mottype
    \param [in] int x
    \param [in] int y
    */
void InitMonstrePerso(Perso * P, typepers T,char* mottype, int x, int y);

/**
    \brief Génère un monstre aléatoirement
    \param [in] Perso * P
    \param [in] int difficulte

    Détermine un type de monstre puis appelle initMonstrePerso
    */
void InitMonstreAleatoirePerso(Perso * P,int difficulte);

/** Testament du joueur **/

/**
    \brief Passe les paramètres à NULL et libère la mémoire
    \param [in] Perso * P

    */
void TestamentJoueurPerso(Perso * P);

/**
    \brief Passe les paramètres à NULL
    \param [in] Perso * P

    Il n'y a pas d'allocation dans la mémoire pour les monstres donc pas besoin de libérer

    */
void TestamentMonstrePerso(Perso * P);

/** Fonction de gestion d'objet **/

/**
    \brief Si P est un joueur : besoin de ramasser les objets dans le jeux, si déja 2 objets dans l'inventaire, pose le premier au sol
    \param [in] Perso * P
    \param [in] Objet * O


    */
void RamasserObjet(Perso * P, Objet * O);

/**
    \brief L'objet secondaire devient objet principal (et vice versa)
    \param [in] Perso * P

    */
void EchangerObjet(Perso * P);



/** Fonction de déplacements (lié au vecteur vitesse) **/
/**
    \brief Fonction de déplacement des monstres
    \return 1 si monstre doit tirer 0 sinon
    \param Perso* monstre
    \param const Perso * P
    */
int deplacementIAPerso(Perso* monstre,const Perso* P);

/**
    \brief met à jour les vecteurs vitesses
    \param [in] Perso * P
    \param [in] float intervalle

    Met à jour les vecteurs vitesses en fonctions des allervert et allerhor
    */
void miseajourvectvitePerso(Perso* P,float intervalle);

/**
    \brief Calcul la position en fonction du vecteur vitesse
    \return double x
    \param [in] Perso * P
    \param [in] float intervalle
    */
double nouvellepositionxPerso(Perso* P,float intervalle);

/**
    \brief Calcul la position en fonction du vecteur vitesse
    \return double y
    \param [in] Perso * P
    \param [in] float intervalle
    */
double nouvellepositionyPerso(Perso* P,float intervalle);

/**
    \brief Fait un arrondi du paramètre
    \return l'arrondi entier en dessous
    \param [in] double coordendouble

    */
int CoordonneeAffichable(double coordendouble);

/**
    \brief Convertit un entier en double
    \return le double
    \param int coordenint

    */
double CoordonneeInterne(int coordenint);

/**
    \brief Gère les collisions des personnages
    \return int 1 si les perso se touche 0 sinon
    \param [in] const Perso * P1
    \param [in] const Perso * P2

    */

int CollisionPerso(const Perso* P1,const Perso* P2);

/**
    \brief Regarde si les point (x,y) est dans la hitbox
    \return 1 si point dans perso 0 sinon
    \param [in] int x
    \param [in] int y
    \param [in] const Perso* P

    */
int PointdansPerso(int x, int y,const Perso* P);


#endif
